#include "lab4-api.h"
#include "usertraps.h"
#include "misc.h"

#include "../include/q3.h"

void main (int argc, char *argv[])
{
  int numprocs = 5;               // Used to store number of processes to create
  int i;                          // Loop index variable
  phil *p;               // Used to get address of shared memory page
  uint32 h_mem;                   // Used to hold handle to shared memory page
  sem_t s_procs_completed;        // Semaphore used to wait until all spawned processes have completed
  char h_mem_str[10];             // Used as command-line argument to pass mem_handle to new processes
  char s_procs_completed_str[10]; // Used as command-line argument to pass page_mapped handle to new processes
  char i_str[2];
  if (argc != 1) {
    Printf("Usage: ");
    Printf(argv[0]);
    Printf("\n");
    Exit();
  }

  Printf("Creating %d processes\n", numprocs);

  // Allocate space for a shared memory page, which is exactly 64KB
  // Note that it doesn't matter how much memory we actually need: we 
  // always get 64KB
  if ((h_mem = shmget()) == 0) {
    Printf("ERROR: could not allocate shared memory page in "); Printf(argv[0]); Printf(", exiting...\n");
    Exit();
  }

  // Map shared memory page into this process's memory space
  if ((p = (phil *)shmat(h_mem)) == NULL) {
    Printf("Could not map the shared page to virtual address in "); Printf(argv[0]); Printf(", exiting..\n");
    Exit();
  }

  // Put some values in the shared memory, to be read by other processes
  for (i = 0; i < 5; i++){
	  p->state[i] = THINKING;
	  p->wait_locks[i] = lock_create();
	  p->self[i] = cond_create(p->wait_locks[i]);
	  p->eaten[i] = 0;

  }



  // Create semaphore to not exit this process until all other processes 
  // have signalled that they are complete.  To do this, we will initialize
  // the semaphore to (-1) * (number of signals), where "number of signals"
  // should be equal to the number of processes we're spawning - 1.  Once 
  // each of the processes has signaled, the semaphore should be back to
  // zero and the final sem_wait below will return.
  if ((s_procs_completed = sem_create(-(numprocs-1))) == SYNC_FAIL) {
    Printf("Bad sem_create in "); Printf(argv[0]); Printf("\n");
    Exit();
  }

  // Setup the command-line arguments for the new process.  We're going to
  // pass the handles to the shared memory page and the semaphore as strings
  // on the command line, so we must first convert them from ints to strings.
  ditoa(h_mem, h_mem_str);
  ditoa(s_procs_completed, s_procs_completed_str);

  // Now we can create the processes.  Note that you MUST end your call to
  // process_create with a NULL argument so that the operating system
  // knows how many arguments you are sending.
  for(i=0; i<numprocs; i++) {
	  ditoa(i, i_str);
    process_create(FILENAME_TO_RUN, h_mem_str, s_procs_completed_str, i_str , NULL);
    Printf("Process %d created\n", i);
  }


  // And finally, wait until all spawned processes have finished.
  if (sem_wait(s_procs_completed) != SYNC_SUCCESS) {
    Printf("Bad semaphore s_procs_completed (%d) in ", s_procs_completed); Printf(argv[0]); Printf("\n");
    Exit();
  }
  for (i = 0; i < numprocs; i++){
	  if (p->eaten[i] == 1){
		  Printf("Philosopher %d has eaten\n", i);
	  }else{
		  Printf("Philosopher %d DID NOT eat\n", i);
	  }
  }

  Printf("All other processes completed, exiting main process.\n");
}
